from editor_base import EditorBase

from ..bases import widgets


class UniverseCombo(widgets.Combo):
    def __init__(self, **kwargs):
        kwargs['list_types'] = [str, str]
        kwargs['name'] = 'Universes'
        super(UniverseCombo, self).__init__(**kwargs)
        self.MainController = kwargs.get('MainController')
        self.DeviceSystem = self.MainController.DeviceSystem
        for key, val in self.DeviceSystem.universes.iteritems():
            self.update({key:val.name})
        keys = self.DeviceSystem.universes.keys()
        if len(keys) == 0:
            univ_id = None
        else:
            univ_id = keys[0]
        self.set_current_selection(key=univ_id)
        

class PatchEditor(EditorBase):
    topwidget_label = 'Patch Editor'
    _Properties = {'patch_count':dict(default=1, min=1, max=512), 
                   'start_chan':dict(default=1, min=1, max=512)}
    def init_editor(self, **kwargs):
        self.definition = kwargs.get('definition')
        self.patch_grid = None
        self._start_chan = 1
        self._patch_count = 1
        hbox = widgets.HBox()
        
        self.patch_grid_container = widgets.ScrolledWindow()
        self.topwidget.pack_start(self.patch_grid_container, expand=True)
        
        self.universe_combo = UniverseCombo(MainController=self.MainController)
        self.universe_combo.connect('selection_changed', self.on_universe_combo_selection_changed)
        
        self.on_universe_combo_selection_changed()
        
        hbox.pack_start(self.universe_combo.topwidget)
        
        self.sbPatchCount = widgets.SpinBtn(label='Device Count', Property=(self, 'patch_count'))
        hbox.pack_start(self.sbPatchCount.topwidget)
        self.sbStartChan = widgets.SpinBtn(label='Start Channel', Property=(self, 'start_chan'))
        btn = widgets.Button(label='Find')
        btn.connect('clicked', self.on_btnFindStartChan_clicked)
        self.sbStartChan.topwidget.pack_start(btn)
        hbox.pack_start(self.sbStartChan.topwidget)
        
        self.topwidget.pack_start(hbox)
        
        self.btn_patch = widgets.Button(label='Patch')
        self.btn_patch.connect('clicked', self.on_btn_patch_clicked)
        self.topwidget.pack_start(self.btn_patch)
        
        self.topwidget.show_all()
            
    def make_patch_grid(self, universe):
        if self.patch_grid:
            self.patch_grid.unlink()
            w = self.patch_grid.topwidget
            w.get_parent().remove(w)
        self.patch_grid = self.make_child_editor(UniversePatchEditor, 'patch_grid', universe=universe)
        self.patch_grid_container.pack_start(self.patch_grid.topwidget)
            
    def on_universe_combo_selection_changed(self, **kwargs):
        key = kwargs.get('key')
        if key is None:
            key = self.universe_combo.current_selection
        self.make_patch_grid(self.DeviceSystem.universes[key])
    
    def on_btnFindStartChan_clicked(self, btn):
        univ_id = self.universe_combo.current_selection
        kwargs = dict(device=self.definition, universe_id=univ_id, count=self.patch_count)
        if univ_id is not None:
            start = self.DeviceSystem.find_first_start_chan(**kwargs)
            if start is False:
                start = 0
            self.start_chan = start
        
    def on_btn_patch_clicked(self, btn):
        univ_id = self.universe_combo.current_selection
        if univ_id is not None:
            device = self.DeviceSystem.patch_device(self.definition, 
                                                    universe_id=univ_id, 
                                                    start_chan=self.start_chan, 
                                                    count=self.patch_count)

class UniverseEditor(EditorBase):
    topwidget_label = 'Universes'
    def init_editor(self, **kwargs):
        self.universe = kwargs.get('universe')
        self.txtName = widgets.Entry(name='Name', Property=(self.universe, 'name'))
        self.topwidget.pack_start(self.txtName.topwidget)
        self.sbIndex = widgets.SpinBtn(label='Universe Index', Property=(self.universe, 'Index'))
        self.topwidget.pack_start(self.sbIndex.topwidget)
        self.sbOLAUnivID = widgets.SpinBtn(label='OLA Universe ID', Property=(self.universe, 'ola_universe_id'))
        self.topwidget.pack_start(self.sbOLAUnivID.topwidget)
        frame = widgets.Frame(label='Artnet Config')
        hbox = widgets.HBox()
        self.sbArtnetSub = widgets.SpinBtn(label='Subnet', Property=(self.universe, 'Artnet_Subnet'))
        hbox.pack_start(self.sbArtnetSub.topwidget)
        self.sbArtnetUniv = widgets.SpinBtn(label='Universe', Property=(self.universe, 'Artnet_Universe'))
        hbox.pack_start(self.sbArtnetUniv.topwidget)
        frame.pack_start(hbox)
        self.topwidget.pack_start(frame)
        #self.patch_editor = self.make_child_editor(UniversePatchEditor, 'patch', universe=self.universe)
        #self.topwidget.pack_start(self.patch_editor.topwidget, expand=True)
        self.value_editor = self.make_child_editor(UniverseValueEditor, 'values', universe=self.universe)
        self.topwidget.pack_start(self.value_editor.topwidget, expand=True)
    def unlink(self):
        super(UniverseEditor, self).unlink()
        keys = ['txtName', 'sbIndex', 'sbOLAUnivID', 'sbArtnetSub', 'sbArtnetUniv']
        for key in keys:
            getattr(self, key).unlink()
        
        
class UniversePatchEditor(EditorBase):
    topwidget_label = 'Patch View'
    def init_editor(self, **kwargs):
        self.universe = kwargs.get('universe')
        self.column_count = kwargs.get('column_count', 32)
        self.row_count = 512 / self.column_count
        self.column_types = [bool] * (self.column_count + 1)
        self.list = gtk.ListStore(*self.column_types)
        self.widget = gtk.TreeView(model=self.list)
        for x in range(self.column_count):
            cell = gtk.CellRendererToggle()
            col = gtk.TreeViewColumn(str(x+1), cell, active=x, activatable=self.column_count + 1)
            self.widget.append_column(col)
        self.topwidget.pack_start(self.widget, expand=True)
        self.update_list()
        self.DeviceSystem.connect('new_device', self.update_list)
        self.DeviceSystem.connect('patch_change', self.update_list)
    def unlink(self):
        super(UniversePatchEditor, self).unlink()
        self.DeviceSystem.disconnect(callback=self.update_list)
    def update_list(self, **kwargs):
        self.list.clear()
        chan = 0
        for y in range(self.row_count):
            row = []
            for x in range(self.column_count):
                chan += 1
                row.append(chan in self.DeviceSystem.patch_by_chan[self.universe.id])
            row.append(False)
            self.list.append(row)
        
class UniverseValueEditor(EditorBase):
    topwidget_label = 'Universe Values'
    def init_editor(self, **kwargs):
        self.universe = kwargs.get('universe')
        self.column_count = kwargs.get('column_count', 32)
        self.row_count = 512 / self.column_count
        self.column_types = [int] * self.column_count
        self.list = gtk.ListStore(*self.column_types)
        self.iters = []
        self.map = []
        for row in range(self.row_count):
            for col in range(self.column_count):
                self.map.append((row, col))
        self.widget = gtk.TreeView(model=self.list)
        for x in range(self.column_count):
            cell = gtk.CellRendererText()
            col = gtk.TreeViewColumn(str(x+1), cell, text=x)
            self.widget.append_column(col)
        self.topwidget.pack_start(self.widget, expand=True)
        self.update_list()
        self.universe.connect('value_update', self.on_universe_value_update)
    def unlink(self):
        self.universe.disconnect(callback=self.on_universe_value_update)
        super(UniverseValueEditor, self).unlink()
    def update_list(self, index=None):
        if index is not None:
            key = self.map[index]
            self.list.set_value(self.iters[key[0]], key[1], self.universe.values[index])
        else:
            for row in range(self.row_count):
                start = self.map.index((row, 0))
                end = start + self.column_count
                row = self.universe.values[start:end]
                self.iters.append(self.list.append(row))
    def on_universe_value_update(self, **kwargs):
        self.update_list(kwargs.get('channel')-1)
